/**
 * @description service auth
 *
 * @author xiaomi
 */

const passport = require('koa-passport');
const LocalStrategy = require('passport-local').Strategy;
const WechatStrategy = require('passport-wechat').Strategy;
const User = require('../models/user');
// const WeiboStrategy = require('passport-weibo').Strategy;
// const TTXSpassport = require('../lib/passport-login');

const md5 = require('../utils/md5');

// const LOGIN_TYPES = {
//     TTXS: 1,
//     WEIBO: 2,
//     WECHAT: 3
// };

// extend authorized
passport.authorized = () => {
    return function * (next) {
        if(this.isUnauthenticated()) {
            this.throw(401, '登录超时');
        }

        if(next) {
            yield next;
        }
        yield next;
    };
};

// serialize, deserialize
passport.serializeUser((user, done) => {
    done(null, user);
});
passport.deserializeUser((user, done) => {
    user = User.forge(user);

    done(null, user);
});

// local - user
passport.authorized = (grade = 'admin') => {
    return function * (next) {
        const user = this.req && this.req.user;
        if(!user && this.isUnauthenticated()) {
            this.throw(401, '非法登录');
        }

        if(grade && grade !== user.get('grade')) {
            this.throw(403, `暂无权限`);
        }

        if(next) {
            yield next;
        }
    };
};

// local - admin
passport.use('admin', new LocalStrategy({
    usernameField: 'account',
    passwordField: 'pwd'
}, (account, pwd, done) => {
    User.query(qb => {
        qb.where(function() {
            this.where('name', account)
            .orWhere('account', account);
        })
        qb.where('pwd', md5(pwd));
    })
    .fetch({
        withRelated: ['role', 'department']
    })
    .then(user => {
        if(!user) {
            const err = new Error('账号或密码错误');
            err.status = 400;

            throw err;
        }
        // Assign grade
        user.set('grade', 'admin');

        user.set('pwd', null);

        done(null, user);
    })
    .catch(done);
}));


// oauth
const WWW_HOST = process.env.WWW_HOST;
const oauthCallbackHost = process.env.WWW_HOST;
const createOAuthCallbackUrl = function(type) {
    let url = `http://${oauthCallbackHost}/users/callback/${type}`;

    if(WWW_HOST !== oauthCallbackHost) {
        let localUrl = `https://${WWW_HOST}/users/callback/${type}`;

        url += '?r=' + encodeURIComponent(localUrl);
    }

    return url;
};

// wechat - 微信登录
passport.use(new WechatStrategy({
    state: 'dcf',
    client: 'web',
    scope: 'snsapi_login',
    appID: process.env.WECHAT_APPID,
    appSecret: process.env.WECHAT_SECTET || 'ceshi',
    callbackURL: createOAuthCallbackUrl('wechat'),
    // @TODO: save to redis
    getToken(openId, callback) {
        callback(null, this.store[openId]);
    },
    saveToken(openId, token, callback) {
        this.store[openId] = token;
        callback(null);
    }
}, (accessToken, refreshToken, profile, expiresIn, done) => {
    done(null, profile);
}));
//
// // weibo - 微博登录
// passport.use(new WeiboStrategy({
//     clientID: process.env.OAUTH_WEIBO_APP_ID,
//     clientSecret: process.env.OAUTH_WEIBO_SECRET || 'ceshi',
//     callbackURL: createOAuthCallbackUrl('weibo'),
// }, (accessToken, refreshToken, profile, done) => {
//     // passport-weibo data fit
//     profile = profile._raw || profile;
//
//     ttxsUser.login(LOGIN_TYPES.WEIBO, {
//         expiresIn: 7200,
//         profile: profile
//     })
//     .then(res => {
//         let user = new User(res);
//
//         // cache oauth data
//         user.$oauth = {
//             type: LOGIN_TYPES.WEIBO,
//             refreshToken,
//             accessToken
//         };
//
//         done(null, user);
//     })
//     .catch(done);
// }));

module.exports = passport;
